package cn.maihe.elg.operation.utils;

import cn.hutool.core.io.FileUtil;
import cn.maihe.elg.operation.model.bo.ApplyTemplatePdfParams;
import cn.maihe.elg.operation.model.bo.GuaranteeTemplatePdfParams;
import cn.maihe.elg.operation.model.bo.ReceiveTemplatePdfParams;
import cn.maihe.elg.operation.model.enums.GuaranteeTemplateType;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import fr.opensagres.xdocreport.itext.extension.font.IFontProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.junit.Test;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.util.ResourceUtils;

import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;

/**
 * @Description dox模板填充
 * @Author WJH
 * @Date 2021/10/11
 */
@Slf4j
public class DocFillUtil {

    public static String simsunPath = null;

    public static Path fillDocTemplate(Path docTemplate, Path targetDoc, Map<String, Object> paramMap) {
        try (
                InputStream sourceTemplateDoc = Files.newInputStream(docTemplate);
                OutputStream targetDocOutput = Files.newOutputStream(targetDoc);
        ) {
            Configure sPELConfigure = Configure.newBuilder().setElMode(Configure.ELMode.SPEL_MODE).build();
            XWPFTemplate template = XWPFTemplate.compile(sourceTemplateDoc, sPELConfigure).render(paramMap);
            template.write(targetDocOutput);
        } catch (Exception e) {
            throw new RuntimeException("doc模板填充数据失败:" + e.getMessage(), e);
        }
        return targetDoc;
    }


    public static Path doc2pdf(Path docPath, Path pdfPath, PdfOptions pdfOptions) {

        //替换为另外实现
//        return doc2pdf(docPath, pdfPath);

        try (
                OutputStream outputStream = Files.newOutputStream(pdfPath);
                InputStream inputStream = Files.newInputStream(docPath);
        ) {
            XWPFDocument doc = new XWPFDocument(inputStream);
            if (pdfOptions == null) {
                pdfOptions = PdfOptions.create();
                pdfOptions.fontProvider(new MyFontProvider());
            }
            PdfConverter.getInstance().convert(doc, outputStream, pdfOptions);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return pdfPath;
    }


    static class MyFontProvider implements IFontProvider {
        @Override
        public com.lowagie.text.Font getFont(String familyName, String encoding, float size, int style, Color color) {
            try {
                com.lowagie.text.pdf.BaseFont bfChinese = com.lowagie.text.pdf.BaseFont.createFont(simsunPath, "Identity-H", com.lowagie.text.pdf.BaseFont.NOT_EMBEDDED);
                com.lowagie.text.Font fontChinese = new com.lowagie.text.Font(bfChinese, size, style, color);
                if (familyName != null) {
                    fontChinese.setFamily(familyName);
                }
                return fontChinese;
            } catch (Exception e) {
                throw new RuntimeException("MyFontProvider.getFont异常：" + e.getMessage());
            }
        }
    }



    public static boolean isExtType(Path path, String extTypesRegex) {
        String extName = FileUtil.extName(path.toFile()).toLowerCase();
        boolean tf = extName.matches(extTypesRegex.toLowerCase());
        return tf;
    }

    @Test
    public void testPdfSynthesis() throws IOException {
        simsunPath = DocFillUtil.class.getResource("/simsun.ttf").getPath();

        Path targetPdfPath = Paths.get("D:\\03muban.pdf");

        //担保保函模板填充后docx文件
        Path sourceDocxPathPlaintext = Paths.get("D:\\03mubanPlaintext.docx");
        //byte[] fileBytes = Files.readAllBytes(sourceDocxPathPlaintext);
        //Files.write(Paths.get("D:\\03mubantemp.docx"), fileBytes, StandardOpenOption.TRUNCATE_EXISTING);
        //未签章pdf文件存储路径
        Path targetPdfPathPlaintext = Paths.get("D:\\03mubanPlaintext.pdf");
        DocFillUtil.doc2pdf(sourceDocxPathPlaintext, targetPdfPathPlaintext, null);


        //担保保函模板填充后docx文件
        Path sourceDocxPathForCiphertext = Paths.get("D:\\03mubanCiphertext.docx");
        //未签章pdf文件存储路径
        Path targetPdfPathForCiphertext = Paths.get("D:\\03mubanCiphertext.pdf");
        //docx转pdf
        DocFillUtil.doc2pdf(sourceDocxPathForCiphertext, targetPdfPathForCiphertext, null);

        try {
            PDFMergerUtility merger = new PDFMergerUtility();
            // 输出文件路径
            merger.setDestinationFileName(targetPdfPath.toAbsolutePath().toString());
            // 输入文件1
            merger.addSource(targetPdfPathForCiphertext.toAbsolutePath().toString());
            // 输入文件2
            merger.addSource(targetPdfPathPlaintext.toAbsolutePath().toString());
            // 执行合并
            merger.mergeDocuments(null);
        } catch (IOException e) {
            throw new RuntimeException("合成pdf失败", e);
        }
    }

    @Test
    public void testApplyTemplate() {
        ApplyTemplatePdfParams params = new ApplyTemplatePdfParams();
        params.setBidderName("投标客户名称投标客户名称投标投标客户名称投客户名称投标客户名称投标客户名称投标客户名称");
        params.setProjectName("项目名称项目名称项目名投标客户名称投称项目名称项目名称项目名称项目名称项目名称项目名称项目名称");
        params.setYear("2021");
        params.setMonth("10");
        params.setDay("21");

        try {
            Path resourcesPath = ResourceUtils.getFile("classpath:").toPath()
                    .resolve("../../src/main/resources").normalize();

            Path templatePath = resourcesPath.resolve("template/01电子保函申请单文件模板.docx");
            Path saveTargetDoc = resourcesPath.resolve("tmp/01电子保函申请单文件.docx");
            Path saveTargetPdf = resourcesPath.resolve("tmp/01电子保函申请单文件.pdf");

            //填充docx模板
            saveTargetDoc = fillDocTemplate(templatePath, saveTargetDoc, BeanMap.create(params));
            //docx转pdf
            saveTargetPdf = doc2pdf(saveTargetDoc, saveTargetPdf, null);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Test
    public void testReceiveTemplate() {
        ReceiveTemplatePdfParams params = new ReceiveTemplatePdfParams();
        params.setGuaranteeNo("ZTDB-1234567890123456789");
        params.setTenderName("称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称");
        params.setBidderName("投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称");
        params.setProjectCode("32132132131NDKFJ1231fdjk");
        params.setProjectName("招标项目名称招标项目名称招标项目名称招标项目名称招标项目名称招标项目名称招标项目名称招标项目名称招标项目名称");
        params.setGuaranteeFee("1,000.10");
        params.setYear("2021");
        params.setMonth("10");
        params.setDay("21");
        params.setPayeeAccNo("62290912346666");
        params.setPayerAccNo("62290912348888");
        params.setSignYear("2021");
        params.setSignMonth("10");
        params.setSignDay("21");
        params.setInstitutionName("泉州丰泽得兴融资担保有限公司");

        try {
            Path resourcesPath = ResourceUtils.getFile("classpath:").toPath()
                    .resolve("../../src/main/resources").normalize();

            Path templatePath = resourcesPath.resolve("template/02到账证明文件模板.docx");
            Path saveTargetDoc = resourcesPath.resolve("tmp/02到账证明文件.docx");
            Path saveTargetPdf = resourcesPath.resolve("tmp/02到账证明文件.pdf");

            //填充docx模板
            saveTargetDoc = fillDocTemplate(templatePath, saveTargetDoc, BeanMap.create(params));
            //docx转pdf
            saveTargetPdf = doc2pdf(saveTargetDoc, saveTargetPdf, null);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Test
    public void testGuaranteeTemplate() {
        GuaranteeTemplatePdfParams params = new GuaranteeTemplatePdfParams();
        params.setGuaranteeTemplateType(GuaranteeTemplateType.fangjian);
        params.setGuaranteeNo("ZTDB-1283928139189331");
        params.setTenderName("受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称受益人名称");
        params.setBidderName("投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称投标人名称");
        params.setProjectName("将乐县南口镇2023年高标准农田建设改造提升项目");
        params.setBidBond(CurrencyUpperUtil.fenToCurrencyUpper(9876543210L));
        params.setSectionName("将乐县南口镇 2023 年高标准农田建设改造提升项目");
        params.setYear("2021");
        params.setMonth("10");
        params.setDay("21");


        try {
            Path resourcesPath = ResourceUtils.getFile("classpath:").toPath()
                    .resolve("../../src/main/resources").normalize();

            Path templatePath = resourcesPath.resolve("template/04房建施工保函模板.docx");
            Path saveTargetDoc = resourcesPath.resolve("tmp/04房建施工保函.docx");
            Path saveTargetPdf = resourcesPath.resolve("tmp/04房建施工保函文件.pdf");

            //填充docx模板
            saveTargetDoc = fillDocTemplate(templatePath, saveTargetDoc, BeanMap.create(params));
            //docx转pdf
            saveTargetPdf = doc2pdf(saveTargetDoc, saveTargetPdf, null);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws Exception {
        DocFillUtil util = new DocFillUtil();
//        util.testApplyTemplate();
//        util.testReceiveTemplate();
//        util.testGuaranteeTemplate();

//
//
        simsunPath = DocFillUtil.class.getResource("/simsun.ttf").getPath();
        Path source = Paths.get("d:/11111111111/04房建施工保函模板.docx");
        Path target = Paths.get("d:/11111111111/04房建施工保函模板.pdf");
//

        DocFillUtil.doc2pdf(source, target, null);


    }
}
